package org.jeecg.modules.chg.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonSendStatus;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.JwMsgTemplateModel;
import org.jeecg.common.system.vo.JwidModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysVarModel;
import org.jeecg.common.thread.MsgThreadService;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.TenantContext;
import org.jeecg.modules.arc.service.IBaseWaterPricesService;
import org.jeecg.modules.arc.vo.BaseWaterPricesVo;
import org.jeecg.modules.bl.entity.BlExpenses;
import org.jeecg.modules.bl.entity.BlSubExpenses;
import org.jeecg.modules.chg.entity.ChgArrears;
import org.jeecg.modules.chg.entity.ChgSubArrear;
import org.jeecg.modules.chg.mapper.ChgArrearsMapper;
import org.jeecg.modules.chg.mapper.ChgSubArrearMapper;
import org.jeecg.modules.chg.service.IChgArrearExpensesService;
import org.jeecg.modules.chg.service.IChgArrearsService;
import org.jeecg.modules.chg.service.IChgFeesService;
import org.jeecg.modules.chg.vo.ChgArrearsPage;
import org.jeecg.modules.rest.service.ISMSCommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: 欠费记录
 * @Author: jeecg-boot
 * @Date:   2022-02-13
 * @Version: V1.0
 */
@Service
public class ChgArrearsServiceImpl extends ServiceImpl<ChgArrearsMapper, ChgArrears>
		implements IChgArrearsService {

	@Autowired
	private ChgArrearsMapper chgArrearsMapper;
	@Autowired
	private ChgSubArrearMapper chgSubArrearMapper;
	@Autowired
	private IChgArrearExpensesService arrearExpensesService;
	@Autowired
	private IBaseWaterPricesService waterPricesService;
	@Autowired
	private IChgFeesService chgFeesService;
	@Autowired
	private ISMSCommonService smsCommonService;
	@Autowired
	private ISysBaseAPI baseAPI;

	@Override
	@Transactional
	public void saveMain(ChgArrears chgArrears, List<ChgSubArrear> chgSubArrearList,String waterReadCycle) {
		if("8".equals(waterReadCycle)){
			chgArrearsMapper.insert(chgArrears);
		}else {
			//欠费-根据cusId+readMonth  一个用户一个月只有一条欠费记录
			List<ChgArrears> oldArrearLs = chgArrearsMapper.selectList(
					new LambdaQueryWrapper<ChgArrears>()
							.eq(ChgArrears::getCusId, chgArrears.getCusId())
							.eq(ChgArrears::getReadMonth, chgArrears.getReadMonth())
							.eq(ChgArrears::getDelFlag, 0));
			if (null != oldArrearLs && oldArrearLs.size() > 0) {
				ChgArrears oldArrears = oldArrearLs.get(0);
				//已存在的欠费记录-直接增加杂项部分
				chgArrears.setAlienMoney(oldArrears.getAlienMoney());
				chgArrears.setMoney(chgArrears.getMoney().add(oldArrears.getAlienMoney()));
				chgArrears.setId(oldArrears.getId());
				chgArrearsMapper.updateById(chgArrears);
			} else {
				chgArrearsMapper.insert(chgArrears);
			}
		}
		if(chgSubArrearList!=null && chgSubArrearList.size()>0) {
			for(ChgSubArrear entity:chgSubArrearList) {
				//外键设置
				entity.setArrearId(chgArrears.getId());
				chgSubArrearMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional
	public void updateMain(ChgArrears chgArrears,List<ChgSubArrear> chgSubArrearList) {
		chgArrearsMapper.updateById(chgArrears);

		//1.先删除子表数据
		chgSubArrearMapper.deleteByMainId(chgArrears.getId());

		//2.子表数据重新插入
		if(chgSubArrearList!=null && chgSubArrearList.size()>0) {
			for(ChgSubArrear entity:chgSubArrearList) {
				//外键设置
				entity.setArrearId(chgArrears.getId());
				chgSubArrearMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional
	public void delMain(String id) {
		chgSubArrearMapper.deleteByMainId(id);
		chgArrearsMapper.deleteById(id);
	}

	//删除水费欠费
	@Override
	public void delSubByMainId(String id) {
		chgSubArrearMapper.deleteByMainId(id);
	}
	//删除水费欠费
	@Override
	public void delAlienSubByMainId(String id) {
		chgSubArrearMapper.deleteAlienByMainId(id);
	}

	@Override
	@Transactional
	public void delAlienMain(String id) {
		chgSubArrearMapper.deleteAlienByMainId(id);
		chgArrearsMapper.deleteById(id);
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			chgSubArrearMapper.deleteByMainId(id.toString());
			chgArrearsMapper.deleteById(id);
		}
	}

	@Override
	public ChgArrearsPage createArrears(Integer isPreinvoiced, JSONObject amountObj
			, BlExpenses expenses, List<BlSubExpenses> blSubExpensesList) {
		List<ChgSubArrear> subArrearsLs=new ArrayList<>();
		for (BlSubExpenses blSubExpenses : blSubExpensesList) {
			ChgSubArrear subArrears = new ChgSubArrear();
			subArrears.setSubExpenseId(blSubExpenses.getId());
			subArrears.setItemCode(blSubExpenses.getItemCode());
			subArrears.setPriceId(blSubExpenses.getPriceId());
			subArrears.setNatureId(blSubExpenses.getNatureId());
			subArrears.setTierNo(blSubExpenses.getTierNo());
			subArrears.setPrice(blSubExpenses.getPrice());
			subArrears.setAmount(blSubExpenses.getAmount());
			subArrears.setArrearAmount(subArrears.getAmount());
			subArrears.setTotalMoney(blSubExpenses.getTotalMoney());
			subArrears.setVatMoney(blSubExpenses.getVatMoney());
			subArrears.setDiscountMoney(blSubExpenses.getDiscountMoney());
			subArrears.setDerateMoney(blSubExpenses.getDerateMoney());
			subArrears.setMoney(blSubExpenses.getMoney());
			subArrears.setArrearMoney(subArrears.getMoney());
			subArrears.setRecivedMoney(new BigDecimal(0.0));
			if(isPreinvoiced ==1){
				//是预开票
				subArrears.setIsLocked(1);
				subArrears.setLockedTypeId("1");
			}else{
				subArrears.setIsLocked(0);
			}
			subArrears.setSyncFlag(0);
			subArrearsLs.add(subArrears);
		}

		BigDecimal zero = new BigDecimal(0.0);
		ChgArrearsPage arrears = new ChgArrearsPage();
		arrears.setCusId(expenses.getCustomerId());
		arrears.setCusName(expenses.getCusName());
		arrears.setNatureId(expenses.getNatureId());
		arrears.setReadMonth(expenses.getReadMonth());

		arrears.setBeginScale( null !=amountObj ? amountObj.getBigDecimal("beginScale") : zero);
		arrears.setEndScale(null !=amountObj ? amountObj.getBigDecimal("endScale"): zero);
		arrears.setReadAmount(null !=amountObj ? amountObj.getBigDecimal("readAmount"): zero);
		arrears.setReplaceAmount(null !=amountObj ? amountObj.getBigDecimal("replaceAmount"): zero);
		arrears.setReplaceMeterScale(null !=amountObj ? amountObj.getBigDecimal("replaceMeterScale"): zero);
		arrears.setAjustedAmount(null !=amountObj ? amountObj.getBigDecimal("ajustedAmount"): zero);
		arrears.setMeasureAmount(null !=amountObj ? amountObj.getBigDecimal("measureAmount"): zero);
		arrears.setAmount(expenses.getAmount());
		arrears.setTotalMoney(expenses.getTotalMoney());
		arrears.setWuMoney(expenses.getWuMoney());
		arrears.setJyMoney(expenses.getJyMoney());
		arrears.setJiMoney(expenses.getJiMoney());
		arrears.setLjMoney(expenses.getLjMoney());
		arrears.setAlienMoney(expenses.getAlienMoney());
		arrears.setVatMoney(expenses.getVatMoney());
		arrears.setDiscountMoney(expenses.getDiscountMoney());
		arrears.setDerateMoney(expenses.getDerateMoney());
		arrears.setMoney(expenses.getMoney());
		arrears.setReaderId(expenses.getReaderId());
		arrears.setBookId(expenses.getBookId());
		//arrears.setReadTime( null != measures.getReadTime() ? DateUtils.formatDate(measures.getReadTime()): null);
		//arrears.setWaterUsedType(measures.getWaterUsedType());
		arrears.setOperatedTime(DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
		arrears.setRecivedAmount(zero);
		arrears.setRecivedMoney(zero);
		arrears.setArrearMoney(arrears.getMoney());
		arrears.setLockedAmount(zero);
		arrears.setLockedMoney(zero);
		arrears.setArrearAmount(arrears.getAmount());
		arrears.setChgSubArrearList(subArrearsLs);
		return arrears;
	}

	@Override
	public List<ChgSubArrear> selectByAccCode(String accCode) {
		return chgSubArrearMapper.selectByAccCode(accCode);
	}

	@Override
	public void expensesPenalty() {

		//SysVarModel penaltyRateModel = baseAPI.querySysVar("penalty_rate");//违约金率
		//SysVarModel penaltyDayModel = baseAPI.querySysVar("penalty_day");//减免延迟违约天数

		/**
		 *
		 * 一般水司在水费逾期缴纳时会收取违约金（滞纳金），本系统提供标准的违约金自动计算方法，在客户在营业厅或银行柜台实时缴纳水费或银行实时代扣时自动产生违约金数额，作为水费的一部分进行缴纳。
		 * 系统提供基于单利计算公式的计算方法：
		 * 违约金 ＝本金×逾期天数×比例。
		 * 系统可以为不同的收费类型用户定义不同的违约金起算日期，违约金起算日期有多种类型可以选择：本月第几日、下月第几日、下期第几日、下下月第几日、抄表后多少天等起算日取值方法。
		 * 系统可以定义违约金的计算比例，可以约束违约金的收取上限，以及违约金的本金范围（是全部水费还是基本水费部分）
		 * 操作人员可以将违约金打印在相关的催费单或出现在客服咨询人员的屏幕上，但需要告知客户这些数据是临时的，只有在客户实际缴纳欠费时才能最后确定，违约金是按天计算的。
		 * 违约金在收取前可以进行打折、直减处理，收取后可以进行冲红处理，违约金可以和水费打印在同一发票上，也可以打印单独的违约金发票。
		 *
		 * 小微-违约金  从下月的1号+应缴日+延迟天数
		 *  缴费日+
		 *  计费日
		 */
		List<ChgArrears> arrearPenaltyLs = chgArrearsMapper.getArrearPenalty();
		if(null != arrearPenaltyLs && arrearPenaltyLs.size()>0){

			for (ChgArrears arrear : arrearPenaltyLs) {
				Integer penaltyDay = arrear.getArrearPenaltyDay();
				//违约金是否超过水费
				Integer isPenaltyExceed = arrear.getPenaltyExceed();
				Integer isOpenPenalty = arrear.getIsOpenPenalty();
				BigDecimal penaltyRate = arrear.getPenaltyRate();

				if(null == isOpenPenalty || isOpenPenalty == 0){
					break;
				}

				//TenantContext.setTenant(arrear.getTenantId()+"");

				//用水性质对应用水价格
				List<BaseWaterPricesVo> pricesVos = waterPricesService
						.queryWaterPriceByNatureId(arrear.getNatureId(),null);

				Map<String,Boolean> itemcodeMap=new HashMap<>();
				for (BaseWaterPricesVo pricesVo : pricesVos) {
					if(pricesVo.getIsPenalty() == 1){
						itemcodeMap.put(pricesVo.getCode(),true);
					}
				}

				//欠费明细-收费项目中参与计算违约金的费用之和
				BigDecimal penaltyTotal=new BigDecimal(0.0);
				BigDecimal penaltyMoney=new BigDecimal(0.0);
				List<ChgSubArrear> subArrearList = chgSubArrearMapper.selectByMainId(arrear.getId());
				for (ChgSubArrear subArrear : subArrearList) {
					if( null != itemcodeMap.get(subArrear.getItemCode())
							&& itemcodeMap.get(subArrear.getItemCode())) {
						penaltyTotal=penaltyTotal.add(subArrear.getMoney());
					}
				}

				if(penaltyTotal.doubleValue()>0){
					//本金×逾期天数×比例。
					penaltyMoney=penaltyTotal.multiply(new BigDecimal(penaltyDay)).multiply(penaltyRate).setScale(2, BigDecimal.ROUND_HALF_UP);

					if (isPenaltyExceed == 0){
						//不超过
						if(penaltyMoney.doubleValue()>arrear.getTotalMoney().doubleValue()){
							penaltyMoney=arrear.getTotalMoney();
						}
					}

					arrear.setArrearMoney(arrear.getArrearMoney().add(penaltyMoney));
					arrear.setPenalty(penaltyMoney);
					arrear.setPenaltyDay(penaltyDay);
					chgArrearsMapper.updateById(arrear);
				}
			}
		}


	}

	//预存账号自动缴费
	@Override
	public void feeAutoPayment() {
		Integer isAutoPayVal=0;

		//需要变量多租户
		//List<TenantModel> tenantList = baseAPI.queryTenant();
		//if(null != tenantList && tenantList.size()>0){
		//	//遍历租户
		//	for (TenantModel tenantModel : tenantList) {
		//		TenantContext.setTenant(tenantModel.getId()+"");

				try {
					SysVarModel isAutoPayModel = baseAPI.querySysVar("isAutoPay");//是否自动缴费
					if(null == isAutoPayModel){
						isAutoPayModel=new SysVarModel();
						isAutoPayModel.setValue("0");
					}
					if(oConvertUtils.isNotEmpty(isAutoPayModel.getValue())){
						isAutoPayVal=Integer.parseInt(isAutoPayModel.getValue());
					}
				}catch (Exception e){
					isAutoPayVal=0;
				}

				if(isAutoPayVal>0){
					List<ChgArrears> arrearAutoPayList = chgArrearsMapper.getArrearAutoPayList();
					if(null != arrearAutoPayList && arrearAutoPayList.size()>0){
						for (ChgArrears chgArrears : arrearAutoPayList) {
							//根据欠费设置多租户
							chgFeesService.storedCharge(chgArrears);
						}
						/**首页数据动态更新-预存扣费*/
						chgFeesService.indexData(null,null);;
					}
				}
		//	}
		//}
	}

	@Override
	public List<ChgArrears> getArrearAutoPayList() {
		return chgArrearsMapper.getArrearAutoPayList();
	}


	/**获取欠费记录及账号信息  */
	@Override
	public List<ChgArrears>getArrearList(ChgArrears chgArrears){
		return chgArrearsMapper.getArrearList(chgArrears);
	}
	/**根据缴费账号获取欠费账单记录  */
	@Override
	public List<ChgArrears>getArrearBillList(String accCode){
		return chgArrearsMapper.selectList(new LambdaQueryWrapper<ChgArrears>()
				.eq(ChgArrears::getCusId,accCode)
				.eq(ChgArrears::getDelFlag,0)
				.orderByAsc(ChgArrears::getReadMonth)
			);
	}

	@Override
	public Result<?> wxMsg(ChgArrears queryWrapper) {

		//List<ChgArrears> arrearsList = chgArrearsMapper.selectList(queryWrapper);
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();


		String tenantId=sysUser.getRelTenantIds();
		JSONObject params=new JSONObject();
		params.put("tenantId",tenantId);
		JwidModel jwModel = baseAPI.getJwId(params);
		List<ChgArrears> arrearsList = chgArrearsMapper.getArrearList(queryWrapper);

		//待发欠费通知
		List<JSONObject> arrearList=new ArrayList<>();

		//账号分组
		JSONObject codeGroupObj = new JSONObject();
		if(null != arrearsList) {
			//按账号分组统计--cus_id
			Set<String>accCodeSet=new HashSet<>();
			for (ChgArrears chgArrear : arrearsList) {
				if (oConvertUtils.isEmpty(chgArrear.getOpenid())) {
					continue;
				}
				JSONObject jo = (JSONObject) JSONObject.toJSON(chgArrear);
				String codeKey = chgArrear.getCusId();/**按水表用户发，不按缴费账号accCode*/
				if (accCodeSet.contains(codeKey)) {
					((ArrayList) codeGroupObj.get(codeKey)).add(jo);
				} else {
					List<JSONObject> codeList = new ArrayList<>();
					codeList.add(jo);
					codeGroupObj.put(codeKey, codeList);
					accCodeSet.add(codeKey);
				}
			}
		}

		//按月份统计-欠费月数： 欠费水量： 欠费总额：
		if(null != codeGroupObj && codeGroupObj.size()>0){
			//http://mwsgzh.usw.cn/#/pages/home/home?jwid=gh_78b3defc9ec3&appid=wx50d1563f095ee8ba
			//http://mwsgzh.usw.cn/#/pages/mp/fee/payFee?jwid=gh_78b3defc9ec3&appid=wx50d1563f095ee8ba
			String url= null != jwModel ? jwModel.getHdUrl() : "";
			if(url.contains("/home/home")){
				url=url.replace("/pages/home/home","/pages/mp/fee/payFee");
			}

			for (String codeKey : codeGroupObj.keySet()) {
				List<JSONObject> codeArrearLs= (List<JSONObject>) codeGroupObj.get(codeKey);
				if(null != codeArrearLs && codeArrearLs.size()>0){
					int index=0;
					BigDecimal waterAmount=new BigDecimal(0.0);
					BigDecimal waterFee=new BigDecimal(0.0);
					BigDecimal accBalance =new BigDecimal(0.0);

					JSONObject noteItem = new JSONObject();

					for (JSONObject arrearObj : codeArrearLs) {
						index++;
						if(index == 1){
							accBalance=arrearObj.getBigDecimal("accBalance");
							noteItem.put("openid",arrearObj.getString("openid"));
							noteItem.put("accCode",codeKey);
							noteItem.put("accName",arrearObj.getString("accName"));
							noteItem.put("url",url);
							noteItem.put("tenantId",arrearObj.getInteger("tenantId")+"");
						}
						waterAmount=waterAmount.add(arrearObj.getBigDecimal("amount"));
						//不含违约金
						BigDecimal money = arrearObj.getBigDecimal("money").subtract(arrearObj.getBigDecimal("recivedMoney"));
						waterFee= waterFee.add(money);
					}
					if(index>0){
						noteItem.put("amount",waterAmount.setScale(0,BigDecimal.ROUND_HALF_UP));
						noteItem.put("money",waterFee);
						noteItem.put("balance",accBalance);
						noteItem.put("count",index);
						arrearList.add(noteItem);
					}
				}
			}
		}

		long s=0;
		if(null != arrearList && arrearList.size()>0){

			String accessToken = jwModel.getAccessToken();
			JwMsgTemplateModel msgTemplate = baseAPI.getMsgFeeBillTemplate(jwModel.getId(), CommonSendStatus.MSG_FEE_ARREARS_NOTICE);
			if (null == msgTemplate) {
				return Result.error("请配置水费欠费通知");
			}
			String tempId = msgTemplate.getTemplateId();

			//多线程处理类目及下线保存
			MsgThreadService<JSONObject> catTool = new MsgThreadService(30, arrearList);
			catTool.setCallBack(new MsgThreadService.CallBack<JSONObject>() {
				@Override
				public void method(List<JSONObject> list) {
					for (int i = 0; i < list.size(); i++) {
						JSONObject item = (JSONObject) list.get(i);
						System.out.println(Thread.currentThread().getId() + "-" + item.getString("cusCode"));
						msgFeeArrearsTemplateSend(accessToken, tempId, item);
					}
				}
			});
			try {
				catTool.excute();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return Result.OK("已发送成功");
	}

	@Override
	public Result<?> smsMsg(ChgArrears queryWrapper) {

		//List<ChgArrears> arrearsList = chgArrearsMapper.selectList(queryWrapper);
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

		SysVarModel isOpenSms = baseAPI.querySysVar("is_open_sms");//是否开启短信服务
		if(null == isOpenSms || "0".equals(isOpenSms.getValue() )){
			return Result.OK("未开启短信服务");
		}

		List<ChgArrears> arrearsList = chgArrearsMapper.getArrearList(queryWrapper);

		//待发欠费通知
		List<JSONObject> arrearList=new ArrayList<>();

		//账号分组
		JSONObject codeGroupObj = new JSONObject();
		if(null != arrearsList) {
			//按账号分组统计
			Set<String>accCodeSet=new HashSet<>();

			for (ChgArrears chgArrear : arrearsList) {
				if(oConvertUtils.isEmpty(chgArrear.getAccPhone())){
					continue;
				}
				if(chgArrear.getAccPhone().trim().length() != 11){
					continue;
				}
				JSONObject jo = (JSONObject) JSONObject.toJSON(chgArrear);
				String codeKey=chgArrear.getAccCode();
				if(accCodeSet.contains(codeKey)){
					((ArrayList)codeGroupObj.get(codeKey)).add(jo);
				}else{
					List<JSONObject> codeList = new ArrayList<>();
					codeList.add(jo);
					codeGroupObj.put(codeKey,codeList);
					accCodeSet.add(codeKey);
				}
			}
		}

		//按月份统计-欠费月数： 欠费水量： 欠费总额：
		if(null != codeGroupObj && codeGroupObj.size()>0){

			for (String codeKey : codeGroupObj.keySet()) {
				List<JSONObject> codeArrearLs= (List<JSONObject>) codeGroupObj.get(codeKey);
				if(null != codeArrearLs && codeArrearLs.size()>0){
					int index=0;
					BigDecimal waterAmount=new BigDecimal(0.0);
					BigDecimal waterFee=new BigDecimal(0.0);
					BigDecimal accBalance =new BigDecimal(0.0);

					JSONObject noteItem = new JSONObject();

					for (JSONObject arrearObj : codeArrearLs) {
						index++;
						if(index == 1){
							accBalance=arrearObj.getBigDecimal("accBalance");
							noteItem.put("accPhone",arrearObj.getString("accPhone"));
							noteItem.put("accCode",codeKey);
							noteItem.put("accCode",codeKey);
							noteItem.put("accName",arrearObj.getString("accName"));
							noteItem.put("tenantId",arrearObj.getInteger("tenantId"));
						}
						waterAmount=waterAmount.add(arrearObj.getBigDecimal("amount"));
						//不含违约金
						BigDecimal money = arrearObj.getBigDecimal("money").subtract(arrearObj.getBigDecimal("recivedMoney"));
						waterFee= waterFee.add(money);
					}
					if(index>0){
						noteItem.put("amount",waterAmount.setScale(0,BigDecimal.ROUND_HALF_UP));
						noteItem.put("money",waterFee);
						noteItem.put("balance",accBalance);
						noteItem.put("count",index);
						arrearList.add(noteItem);
					}
				}
			}
		}

		long s=0;
		if(null != arrearList && arrearList.size()>0){

			//多线程发送处理
			MsgThreadService<JSONObject> catTool = new MsgThreadService(30, arrearList);
			catTool.setCallBack(new MsgThreadService.CallBack<JSONObject>() {
				@Override
				public void method(List<JSONObject> list) {
					for (int i = 0; i < list.size(); i++) {
						JSONObject item = (JSONObject) list.get(i);
						System.out.println(Thread.currentThread().getId() + "-" + item.getString("accCode"));
						smsFeeArrearsSend(item);
					}
				}
			});
			try {
				catTool.excute();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return Result.OK("已发送成功");
	}

	//水费欠费停水通知
	@Override
	public Result<?> smsStopMsg(ChgArrears queryWrapper) {

		//List<ChgArrears> arrearsList = chgArrearsMapper.selectList(queryWrapper);
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

		SysVarModel isOpenSms = baseAPI.querySysVar("is_open_sms");//是否开启短信服务
		if(null == isOpenSms || "0".equals(isOpenSms.getValue() )){
			return Result.OK("未开启短信服务");
		}

		List<ChgArrears> arrearsList = chgArrearsMapper.getArrearList(queryWrapper);

		//待发欠费通知
		List<JSONObject> arrearList=new ArrayList<>();

		//账号分组
		JSONObject codeGroupObj = new JSONObject();
		if(null != arrearsList) {
			//按账号分组统计
			Set<String>accCodeSet=new HashSet<>();

			for (ChgArrears chgArrear : arrearsList) {
				if(oConvertUtils.isEmpty(chgArrear.getAccPhone())){
					continue;
				}
				if(chgArrear.getAccPhone().trim().length() != 11){
					continue;
				}
				JSONObject jo = (JSONObject) JSONObject.toJSON(chgArrear);
				String codeKey=chgArrear.getAccCode();
				if(accCodeSet.contains(codeKey)){
					((ArrayList)codeGroupObj.get(codeKey)).add(jo);
				}else{
					List<JSONObject> codeList = new ArrayList<>();
					codeList.add(jo);
					codeGroupObj.put(codeKey,codeList);
					accCodeSet.add(codeKey);
				}
			}
		}

		//按月份统计-欠费月数： 欠费水量： 欠费总额：
		if(null != codeGroupObj && codeGroupObj.size()>0){

			for (String codeKey : codeGroupObj.keySet()) {
				List<JSONObject> codeArrearLs= (List<JSONObject>) codeGroupObj.get(codeKey);
				if(null != codeArrearLs && codeArrearLs.size()>0){
					int index=0;
					BigDecimal waterAmount=new BigDecimal(0.0);
					BigDecimal waterFee=new BigDecimal(0.0);
					BigDecimal accBalance =new BigDecimal(0.0);

					JSONObject noteItem = new JSONObject();

					for (JSONObject arrearObj : codeArrearLs) {
						index++;
						if(index == 1){
							accBalance=arrearObj.getBigDecimal("accBalance");
							noteItem.put("accPhone",arrearObj.getString("accPhone"));
							noteItem.put("accCode",codeKey);
							noteItem.put("accCode",codeKey);
							noteItem.put("accName",arrearObj.getString("accName"));
							noteItem.put("tenantId",arrearObj.getInteger("tenantId"));
						}
						waterAmount=waterAmount.add(arrearObj.getBigDecimal("amount"));
						//不含违约金
						BigDecimal money = arrearObj.getBigDecimal("money").subtract(arrearObj.getBigDecimal("recivedMoney"));
						waterFee= waterFee.add(money);
					}
					if(index>3){
						noteItem.put("amount",waterAmount.setScale(0,BigDecimal.ROUND_HALF_UP));
						noteItem.put("money",waterFee);
						noteItem.put("balance",accBalance);
						noteItem.put("count",index);
						arrearList.add(noteItem);
					}
				}
			}
		}

		long s=0;
		if(null != arrearList && arrearList.size()>0){

			//多线程发送处理
			MsgThreadService<JSONObject> catTool = new MsgThreadService(30, arrearList);
			catTool.setCallBack(new MsgThreadService.CallBack<JSONObject>() {
				@Override
				public void method(List<JSONObject> list) {
					for (int i = 0; i < list.size(); i++) {
						JSONObject item = (JSONObject) list.get(i);
						System.out.println(Thread.currentThread().getId() + "-" + item.getString("accCode"));
						smsStopFeeArrearsSend(item);
					}
				}
			});
			try {
				catTool.excute();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return Result.OK("已发送成功");
	}

	/***微信支付回调通知-主动查找订单状态*/
	@Override
	public void feeWeixinPayNotify() {

	}

	/**水费欠费通知 MSG_FEE_ARREARS_NOTICE
	 {{first.DATA}}
	 用户名称：{{keyword1.DATA}}
	 欠费月数：{{keyword2.DATA}}
	 欠费水量：{{keyword3.DATA}}
	 欠费总额：{{keyword4.DATA}}
	 预存余额：{{keyword5.DATA}}
	 {{remark.DATA}}

	 尊敬用户，截止到2016年07月12日您还有以下水费未结清，请及时缴费，谢谢您的理解。
	 用户名称：*一山
	 欠费月数：共2个月
	 欠费水量：100吨
	 欠费总额：301.00元
	 预存余额：209.00元温馨提示：欠费总额不含违约金，违约金以实际缴费金额为准；预存余额小于当月水费金额时将暂时不扣款，您可继续预存充足余额后将自动抵扣，谢谢理解。
	 * **/
	public void msgFeeArrearsTemplateSend(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","尊敬的用户"+DateUtils.getDate("yyyy年MM月dd日")+"您还有以下水费未结清，请及时缴费，谢谢您的理解。");
		noteItem.put("keynote1",item.getString("accName")+"("+item.getString("accCode")+")");
		noteItem.put("keynote2","共"+ null != item.get("count") ? item.getString("count") : "1" + "个月");
		noteItem.put("keynote3",item.getBigDecimal("amount").intValue()+"吨");

		//欠费总额 /**欠费总额不含违约金*/
		BigDecimal zear=new BigDecimal(0);
		noteItem.put("keynote4",item.getBigDecimal("money").setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
		//预存余额
		BigDecimal addMoney = (null!= item.get("balance") ? item.getBigDecimal("balance") : zear);
		noteItem.put("keynote5",addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");

		noteItem.put("remark","温馨提示：欠费总额不含违约金，违约金以实际缴费金额为准；预存余额小于当月水费金额时将暂时不扣款，您可继续预存充足余额后将自动抵扣，谢谢理解");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());
	}
	/**水费欠费通知 MSM
	 * **/
	public void smsFeeArrearsSend(JSONObject item){

//欠费总额 /**欠费总额不含违约金*/
		BigDecimal zear=new BigDecimal(0);
		//预存余额
		BigDecimal addMoney = (null!= item.get("balance") ? item.getBigDecimal("balance") : zear);
		StringBuffer sb=new StringBuffer();
		//签名
		String signName=item.getString("tenantId").equals("16")?"诗山自来水厂":"MWS水务平台";
		if("16".equals(item.getString("tenantId"))){
			sb.append("【"+signName+"】尊敬的用户："+item.getString("accName")+"("+item.getString("accCode")+")");
			sb.append("，至"+DateUtils.getDate("yyyy年MM月dd日"));
			sb.append(",您的水费账单还欠"+item.getBigDecimal("money").setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
			sb.append("，请及时缴费，谢谢您的理解！服务热线：0595-86486798");
		}else{
			sb.append("【"+signName+"】尊敬的用户"+item.getString("accName")+"("+item.getString("accCode")+")"+"您还有以下水费未结清,");
			sb.append("共");
			sb.append(null != item.get("count") ? item.getString("count") : "1");
			sb.append("个月;");
			sb.append("水量："+item.getBigDecimal("amount").intValue()+"吨");
			sb.append("；水费："+item.getBigDecimal("money").setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
			//sb.append("；余额："+addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
			sb.append("，请及时缴费，谢谢您的理解！");
		}

		JSONObject noteItem=new JSONObject();
		noteItem.put("uid",item.getString("accCode")+ UuidUtils.getUUID().substring(0,8));
		noteItem.put("content",sb.toString());
		noteItem.put("destMobiles",item.getString("accPhone"));
		/**
		 * * req.setUid(uid);                 [选填] 业务标识，由贵司自定义32为数字透传至我司
		 * req.setCust_code(custCode);      [必填] 用户账号  config 自带
		 * req.setContent(content);         [必填] 短信内容
		 * req.setDestMobiles(destMobiles); [必填] 接收号码，同时发送给多个号码时,号码之间用英文半角逗号分隔(,)
		 */
		JSONObject resultObj = smsCommonService.sendSms("/sendSms", noteItem);

		//微信消息记录-短信
		String msgRecordCode="402881a9802c683001802c6830980000";
		JSONObject jsonMsgObj=new JSONObject();
		//jsonUnRead.put("book_id",customers.get);
		jsonMsgObj.put("title", "1");//类型
		jsonMsgObj.put("way", "2");//通道
		jsonMsgObj.put("tenant_id", item.getInteger("tenantId"));//租户
		jsonMsgObj.put("acc_code",item.getString("accCode"));
		jsonMsgObj.put("touser",item.getString("accPhone"));
		jsonMsgObj.put("template_id",resultObj.toJSONString());
		jsonMsgObj.put("content",noteItem.toJSONString());
		jsonMsgObj.put("msg_status",null != resultObj ? resultObj.getString("respCode"): "1");
		jsonMsgObj.put("create_time",DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));

		this.baseAPI.createOnlineData(msgRecordCode,jsonMsgObj);
		log.warn(new Date()+"-msgSend发送短信消息结果："+noteItem.toJSONString());
	}

	/**水费欠费停水通知 MSM
	 *
	 * **/
	public void smsStopFeeArrearsSend(JSONObject item){
		BigDecimal zear=new BigDecimal(0);
		//预存余额
		BigDecimal addMoney = (null!= item.get("balance") ? item.getBigDecimal("balance") : zear);
		StringBuffer sb=new StringBuffer();

		//签名
		String signName=item.getString("tenantId").equals("16")?"诗山自来水厂":"MWS水务平台";

		sb.append("【"+signName+"】尊敬的"+item.getString("accName")+"用户 (户号："+item.getString("accCode")+")，"
				+"根据《福建省城乡供水条例》，第四十条相关规定。于");

		sb.append(DateUtils.getDate("yyyy年MM月dd日"));
		sb.append("共欠");
		sb.append(item.getBigDecimal("money").setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元水费,");
		sb.append("我厂已对你进行多次催缴水费，一直未完成缴纳。现限你于接收本条信息三个工作日内完成缴款。如未按时缴纳，我厂将暂停对你的供水服务。");

		//服务电话
		String telStr= item.getString("tenantId").equals("16")? "电话：86486798": "";
		sb.append("请及时缴费，谢谢您的理解！"+ telStr);

		JSONObject noteItem=new JSONObject();
		noteItem.put("uid",item.getString("accCode")+ UuidUtils.getUUID().substring(0,8));
		noteItem.put("content",sb.toString());
		noteItem.put("destMobiles",item.getString("accPhone"));
		/**
		 * * req.setUid(uid);                 [选填] 业务标识，由贵司自定义32为数字透传至我司
		 * req.setCust_code(custCode);      [必填] 用户账号  config 自带
		 * req.setContent(content);         [必填] 短信内容
		 * req.setDestMobiles(destMobiles); [必填] 接收号码，同时发送给多个号码时,号码之间用英文半角逗号分隔(,)
		 */
		JSONObject resultObj = smsCommonService.sendSms("/sendSms", noteItem);
		String status="";
		if(null != resultObj ){
			if("success".equals(resultObj.getString("status").toLowerCase())){
				status="success";
			}else{
				status="failed";
			}
		}

		//微信消息记录-短信
		String msgRecordCode="402881a9802c683001802c6830980000";
		JSONObject jsonMsgObj=new JSONObject();
		//jsonUnRead.put("book_id",customers.get);
		jsonMsgObj.put("title", "1");//类型
		jsonMsgObj.put("way", "2");//通道
		jsonMsgObj.put("remark", status);//备注 success failed
		jsonMsgObj.put("tenant_id", item.getInteger("tenantId"));//租户
		jsonMsgObj.put("acc_code",item.getString("accCode"));
		jsonMsgObj.put("touser",item.getString("accPhone"));
		jsonMsgObj.put("template_id",resultObj.toJSONString());
		jsonMsgObj.put("content",noteItem.toJSONString());
		jsonMsgObj.put("msg_status",null != resultObj ? resultObj.getString("respCode"): "1");
		jsonMsgObj.put("create_time",DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));

		this.baseAPI.createOnlineData(msgRecordCode,jsonMsgObj);
		log.warn(new Date()+"-msgSend发送短信消息结果："+noteItem.toJSONString());
	}

	/**欠费停水通知 MSG_FEE_STOP_NOTICE
		 {{first.DATA}}
		 账户编号：{{keyword1.DATA}}
		 账户名称：{{keyword2.DATA}}
		 欠费金额：{{keyword3.DATA}}
		 账户余额：{{keyword4.DATA}}
		 停水时间：{{keyword5.DATA}}
		 {{remark.DATA}}

		 您的账户已欠费，即将停水
		 账户编号：0008001
		 账户名称：张三
		 欠费金额：100.00元
		 账户余额：0元
		 停水时间：2016年11月11日请及时缴清费用，以免影响您的用水。
		 详询22988807
	 * **/
	public void msgFeeStopTemplateSend(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","尊敬的"+item.getString("accName")+"，您好！您的账户在"+item.getString("readMonth")+"月的水费账单如下：");
		noteItem.put("keynote1",item.getBigDecimal("beginScale").intValue()+"");
		noteItem.put("keynote2",item.getBigDecimal("endScale").intValue()+"");
		noteItem.put("keynote3",item.getBigDecimal("readAmount").intValue()+"吨");

		//其他费用 杂项+违约金
		BigDecimal zear=new BigDecimal(0);
		BigDecimal addMoney = (null!= item.get("alienMoney") ? item.getBigDecimal("alienMoney") : zear)
				.add(null!= item.get("penalty") ? item.getBigDecimal("penalty") : zear);
		noteItem.put("keynote4",addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");

		BigDecimal subMoney = (null!= item.get("arrearMoney") ? item.getBigDecimal("arrearMoney") : zear)
				.subtract(null!= item.get("recivedMoney") ? item.getBigDecimal("recivedMoney") : zear);
		noteItem.put("keynote5",subMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
		noteItem.put("remark","请及时缴费。如已结清请忽略本提醒。！");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());
	}

	/**水费账单提醒 MSG_FEE_BILL_NOTICE
		 {{first.DATA}}
		 用户编号：{{keyword1.DATA}}
		 用户名称：{{keyword2.DATA}}
		 用户地址：{{keyword3.DATA}}
		 计费年月：{{keyword4.DATA}}
		 抄表水量：{{keyword5.DATA}}
		 {{remark.DATA}}

		 尊敬的客户，您本期水费信息如下
		 用户编号：12345678
		 用户名称：张三四
		 用户地址：和平路12号
		 计费年月：201604
		 抄表水量：15.00水费金额：19.5元 垃圾费金额：22元 排污费金额：10.8元 合计金额：52.3元 如有疑问，请致电水务热线：2828226。
	 * **/
	public void msgFeeBillTemplateSend(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","尊敬的"+item.getString("accName")+"，您好！您的账户在"+item.getString("readMonth")+"月的水费账单如下：");
		noteItem.put("keynote1",item.getBigDecimal("beginScale").intValue()+"");
		noteItem.put("keynote2",item.getBigDecimal("endScale").intValue()+"");
		noteItem.put("keynote3",item.getBigDecimal("readAmount").intValue()+"吨");

		//其他费用 杂项+违约金
		BigDecimal zear=new BigDecimal(0);
		BigDecimal addMoney = (null!= item.get("alienMoney") ? item.getBigDecimal("alienMoney") : zear)
				.add(null!= item.get("penalty") ? item.getBigDecimal("penalty") : zear);
		noteItem.put("keynote4",addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");

		BigDecimal subMoney = (null!= item.get("arrearMoney") ? item.getBigDecimal("arrearMoney") : zear)
				.subtract(null!= item.get("recivedMoney") ? item.getBigDecimal("recivedMoney") : zear);
		noteItem.put("keynote5",subMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
		noteItem.put("remark","请及时缴费。如已结清请忽略本提醒。！");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());

	}
	/**停水通知 MSG_WATER_STOP_NOTICE
	 {{first.DATA}}
	 停水类型：{{keyword1.DATA}}
	 停水时间：{{keyword2.DATA}}
	 停水区域：{{keyword3.DATA}}
	 {{remark.DATA}}

	 江西省萍乡市城区停水通知
	 停水类型：计划检修
	 停水时间：2014年8月29日8:00-18:00
	 停水区域：安源区步行街、北桥、万龙湾因为城区道路改造需要对自来水供水管路进行停水履行，给您带来不便敬请谅解。
	 市政公告。

	 * **/
	public void msgWaterStopTemplateSend(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","尊敬的"+item.getString("accName")+"，您好！您的账户在"+item.getString("readMonth")+"月的水费账单如下：");
		noteItem.put("keynote1",item.getBigDecimal("beginScale").intValue()+"");
		noteItem.put("keynote2",item.getBigDecimal("endScale").intValue()+"");
		noteItem.put("keynote3",item.getBigDecimal("readAmount").intValue()+"吨");

		//其他费用 杂项+违约金
		BigDecimal zear=new BigDecimal(0);
		BigDecimal addMoney = (null!= item.get("alienMoney") ? item.getBigDecimal("alienMoney") : zear)
				.add(null!= item.get("penalty") ? item.getBigDecimal("penalty") : zear);
		noteItem.put("keynote4",addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");

		BigDecimal subMoney = (null!= item.get("arrearMoney") ? item.getBigDecimal("arrearMoney") : zear)
				.subtract(null!= item.get("recivedMoney") ? item.getBigDecimal("recivedMoney") : zear);
		noteItem.put("keynote5",subMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
		noteItem.put("remark","请及时缴费。如已结清请忽略本提醒。！");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());

	}
	/**缴费成功通知 MSG_PAY_SUCCESS_NOTICE
	 {{first.DATA}}
	 收费单位：{{keyword1.DATA}}
	 缴费账号：{{keyword2.DATA}}
	 交易时间：{{keyword3.DATA}}
	 缴费金额：{{keyword4.DATA}}
	 {{remark.DATA}}

	 你的订单已缴费成功。
	 收费单位：深圳供电局（关内区）
	 缴费账号：111111
	 交易时间：2013-12-10 10:17:57
	 缴费金额：100.
	 00元您可以到缴费记录查看更多信息

	 * **/
	public void msgPaySuccessTemplateSend(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","恭喜您水费缴费成功，本次缴费订单号:"+item.getString("orderNo"));
		noteItem.put("keynote1",item.getString("jwidName"));
		noteItem.put("keynote2",item.getString("accCode"));
		noteItem.put("keynote3",DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));

		//缴费金额
		noteItem.put("keynote4",item.getBigDecimal("money").setScale(2, BigDecimal.ROUND_HALF_UP)+"元");
		noteItem.put("remark","您可以到缴费记录查看更多信息");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());

	}
	/**
	 * 水费账单提醒 IT科技类模板  MSG_FEE_BILL_NOTICE
	 * {{first.DATA}}
	 * 上期读数：{{keyword1.DATA}}
	 * 本期读数：{{keyword2.DATA}}
	 * 本期用量：{{keyword3.DATA}}
	 * 其他费用：{{keyword4.DATA}}
	 * 本期总费用：{{keyword5.DATA}}
	 * {{remark.DATA}}
	 * **/
	public void msgFeeBillTemplateIT(String accessToken,String temId, JSONObject item){

		JSONObject noteItem=new JSONObject();

		noteItem.put("openid",item.getString("openid"));
		noteItem.put("accCode",item.getString("accCode"));
		noteItem.put("url",item.getString("url"));

		noteItem.put("first","尊敬的"+item.getString("accName")+"，您好！您的账户在"+item.getString("readMonth")+"月的水费账单如下：");
		noteItem.put("keynote1",item.getBigDecimal("beginScale").intValue()+"");
		noteItem.put("keynote2",item.getBigDecimal("endScale").intValue()+"");
		noteItem.put("keynote3",item.getBigDecimal("readAmount").intValue()+"吨");

		//其他费用 杂项+违约金
		BigDecimal zear=new BigDecimal(0);
		BigDecimal addMoney = (null!= item.get("alienMoney") ? item.getBigDecimal("alienMoney") : zear)
				.add(null!= item.get("penalty") ? item.getBigDecimal("penalty") : zear);
		noteItem.put("keynote4",addMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");

		BigDecimal subMoney = (null!= item.get("arrearMoney") ? item.getBigDecimal("arrearMoney") : zear)
				.subtract(null!= item.get("recivedMoney") ? item.getBigDecimal("recivedMoney") : zear);
		noteItem.put("keynote5",subMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()+"元");
		noteItem.put("remark","请及时缴费。如已结清请忽略本提醒。！");

		JSONObject jsonObject = baseAPI.msgSend(accessToken, temId, noteItem);
		log.debug(new Date()+"-msgSend发送微信消息结果："+jsonObject.toJSONString());

	}

}
